package com.itheima.service.impl;

import com.itheima.common.utils.DateUtils;
import com.itheima.mapper.MemberMapper;
import com.itheima.pojo.*;
import com.itheima.service.MemberService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFName;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.*;

@Slf4j
@Service
public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberMapper memberMapper;

    //会员统计
    public MemberCountVo getMemberReport() throws Exception {
        //存储日期
        List<String> date = new ArrayList<>();
        //存储数量
        List<Integer> count = new ArrayList<>();
        //获取日期 开始月份
        LocalDate begin = LocalDate.now().minusMonths(12);
        //获取第一个月的最后一天
        LocalDate dayOfMonth = DateUtils.getLastDayOfMonth(begin.getYear(), begin.getMonthValue());
        log.info("开始日期：{}", dayOfMonth);
        //获取结束月份
        LocalDate end = LocalDate.now().minusMonths(1);
        //获取结束日期
        LocalDate endOfMonth = DateUtils.getLastDayOfMonth(end.getYear(), end.getMonthValue());
        log.info("结束日期：{}", endOfMonth);

        while (dayOfMonth.isBefore(endOfMonth)) {
            //转换为Date 字符串
            Date date1 = Date.from(dayOfMonth.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date date2 = Date.from(dayOfMonth.plusMonths(1).atStartOfDay(ZoneId.systemDefault()).toInstant());

            String beginDate = DateUtils.parseDate2String(date1);
            String endDate = DateUtils.parseDate2String(date2);

            Map map = new HashMap<>();
            map.put("begin", beginDate);
            map.put("end", endDate);

            date.add(beginDate);
            Integer count1 = memberMapper.getMemberReport(map);
            count.add(count1);
            dayOfMonth = dayOfMonth.plusMonths(1);
            dayOfMonth = DateUtils.getLastDayOfMonth(dayOfMonth.getYear(), dayOfMonth.getMonthValue());

        }
        return new MemberCountVo(date, count);

    }


    //套餐统计
    public SetmealCountVo getSetmealReport() throws Exception {

//        SetmealCountVo vo = new SetmealCountVo();

        List<SetmealCount> setmealCount = new ArrayList<>();
        List<String> setmealNames = new ArrayList<>();
        //开始日期
        LocalDate begin = LocalDate.now().minusMonths(12);
        log.info("开始日期：{}", begin);
        //结束日期
        LocalDate end = LocalDate.now().minusMonths(1);
        log.info("结束日期：{}", end);


        //转换为Date 字符串
        Date date1 = Date.from(begin.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date date2 = Date.from(end.atStartOfDay(ZoneId.systemDefault()).toInstant());

        String beginDate = DateUtils.parseDate2String(date1);
        String endDate = DateUtils.parseDate2String(date2);

        Map map = new HashMap<>();
        map.put("begin", beginDate);
        map.put("end", endDate);
        //查询数据库

        List<SetmealCount> setmealCount1 = memberMapper.getSetmealReport(map);

        for (SetmealCount setmeal : setmealCount1) {
            setmealNames.add(setmeal.getName());
            setmealCount.add(setmeal);
        }

        return new SetmealCountVo(setmealNames, setmealCount1);
    }

    //运营数据统计
    public ReportVo getBusinessReportData() throws Exception {
        //获取今天的日期
        Date today = DateUtils.getToday();

        String end = DateUtils.parseDate2String(today);
        //获取本周一
        Date weekDate = DateUtils.getThisWeekMonday(today);
        String week = DateUtils.parseDate2String(weekDate);
        //获取本月第一天日期
        Date date = DateUtils.getFirstDay4ThisMonth();
        String month = DateUtils.parseDate2String(date);

        //获取会员的统计数据 总数
        Integer ReportMember = memberMapper.getMemberNumber("", end);
        //获取会员今日的统计数据
        Integer ReportToday = memberMapper.getMemberNumber(end, end);
        //获取会员本周的统计数据
        Integer ReportWeek = memberMapper.getMemberNumber(week, end);
        //获取会员本月的统计数据
        Integer ReportMonth = memberMapper.getMemberNumber(month, end);

        //获取今日预约的统计数据
        Integer ReportOrder = memberMapper.getOrderNumber(null, end, end);
        //获取本周预约的统计数据
        Integer ReportWeekOrder = memberMapper.getOrderNumber(null, week, end);
        //获取本月预约的统计数据
        Integer ReportMonthOrder = memberMapper.getOrderNumber(null, month, end);

        //获取今日到诊的统计数据
        Integer ReportOrders = memberMapper.getOrderNumber(Order.ORDERSTATUS_YES, end, end);
        //获取本周到诊的统计数据
        Integer ReportWeekOrders = memberMapper.getOrderNumber(Order.ORDERSTATUS_YES, week, end);
        //获取本月到诊的统计数据
        Integer ReportMonthOrders = memberMapper.getOrderNumber(Order.ORDERSTATUS_YES, month, end);

        Map map = new HashMap<>();
        map.put("begin", month);
        map.put("end", end);

        //获取套餐统计数据
        List<SetmealCount> list = memberMapper.getSetmealReport(map);

        List<SetmealCount> setmealCount = new ArrayList<>();

        Integer total = 0;

        for (SetmealCount count : list) {
            total += count.getValue();
        }

        for (SetmealCount count : list) {

            SetmealCount setmealCount1item = new SetmealCount();
            if (total != 0 && count.getValue() != 0) { // 避免除以零的情况
                double proportion = (count.getValue() * 100.0) / total;
                String s = String.format("%.4f", proportion);
                setmealCount1item.setProportion(s);
            } else {
                setmealCount1item.setProportion("0.00");
            }
            setmealCount1item.setName(count.getName());
            setmealCount1item.setValue(count.getValue());
            setmealCount.add(setmealCount1item);
        }
        //封装数据
        return ReportVo.builder()
                .todayVisitsNumber(ReportOrders.toString())
                .reportDate(end)
                .todayNewMember(ReportToday.toString())
                .thisWeekVisitsNumber(ReportWeekOrder.toString())
                .hotSetmeal(setmealCount)
                .thisMonthNewMember(ReportMonth.toString())
                .thisWeekNewMember(ReportWeek.toString())
                .totalMember(ReportMember.toString())
                .thisMonthOrderNumber(ReportMonthOrder.toString())
                .thisMonthVisitsNumber(ReportMonthOrders.toString())
                .todayOrderNumber(ReportOrder.toString())
                .thisWeekOrderNumber(ReportWeekOrder.toString())
                .build();
    }

    //模板下载

    @Override
    public void outputExcel(HttpServletResponse response) {

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("content-Disposition", "attachment;filename=report_template.xlsx");

        //读取模板文件
        try {
            //获取统计数据
            ReportVo data = getBusinessReportData();
            //读取模板文件
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");
            XSSFWorkbook excle = new XSSFWorkbook(inputStream);

            //获取sheet
            XSSFSheet sheet = excle.getSheetAt(0);

            //获取sheet页的第三行
            sheet.getRow(2).getCell(5).setCellValue(data.getReportDate());
            //获取第5行
            XSSFRow row5 = sheet.getRow(4);
            row5.getCell(5).setCellValue(data.getTodayNewMember());
            row5.getCell(7).setCellValue(data.getTotalMember());
            //获取第6行
            XSSFRow row6 = sheet.getRow(5);
            row6.getCell(5).setCellValue(data.getTodayOrderNumber());
            row6.getCell(7).setCellValue(data.getThisMonthOrderNumber());
            //获取第8行
            XSSFRow row8 = sheet.getRow(7);
            row8.getCell(5).setCellValue(data.getTodayVisitsNumber());
            row8.getCell(7).setCellValue(data.getThisMonthVisitsNumber());
            //获取第9行
            XSSFRow row9 = sheet.getRow(8);
            row9.getCell(5).setCellValue(data.getThisWeekNewMember());
            row9.getCell(7).setCellValue(data.getThisWeekOrderNumber());
            //获取第10行
            XSSFRow row10 = sheet.getRow(9);
            row10.getCell(5).setCellValue(data.getThisWeekVisitsNumber());
            row10.getCell(7).setCellValue(data.getThisWeekVisitsNumber());

            //设置是热门套餐
            for (int i = 0; i < data.getHotSetmeal().size(); i++) {
                XSSFRow row = sheet.getRow(13 + i);
                row.getCell(4).setCellValue(data.getHotSetmeal().get(i).getName());
                row.getCell(5).setCellValue(data.getHotSetmeal().get(i).getValue());
                row.getCell(6).setCellValue(data.getHotSetmeal().get(i).getProportion());
            }

            ServletOutputStream stream = response.getOutputStream();
            excle.write(stream);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}


